#include <iostream>
#include <string>
#include <vector>
#include <boost/filesystem.hpp>

#include "common.hpp"
#include "log.hpp"

Log server_log;

namespace qyc
{
    // 该目录下存放所有的html文档
    const std::string src_path = "./data/input";
    // 清理后的html文档信息存放文件
    const std::string raw_file = "./data/raw_html/raw.bin";

    bool enum_file(const std::string& path, std::vector<std::string>& files)
    {
        namespace fs = boost::filesystem;
        fs::path root_path(path);
        // 判断路径是否存在
        if (!fs::exists(root_path))
        {
            // std::cerr << path << " path no exists" << std::endl;
            server_log(Fatal, "%s path no exists, err file: %s, err line: %s", path.c_str(), __FILE__, __LINE__);
            return false;
        }
        // 定义一个空的迭代器,用于判定递归迭代结束
        fs::recursive_directory_iterator end;
        for (fs::recursive_directory_iterator iter(root_path); iter != end; ++iter)
        {
            // 判断是否为普通文件
            if (!fs::is_regular_file(*iter))
                continue;
            // 检测文件后缀是否为.html
            // path()提取当前路径的fs::path对象 extension提取文件路径后缀
            if (iter->path().extension() != ".html")
                continue;
            // 当前路径一定是一个合法的,以.html结束的普通网页文件
            // 将路径保存,为后续清理解析
            files.push_back(iter->path().string());
    #ifdef __TEST__DEBUG__1
            std::cout << "Debug: " << files.back() << std::endl;
    #endif
        }
        return true;
    }

    bool parse_html(const std::vector<std::string>& files, std::vector<doc_info_t>& htmls)
    {
        for (const std::string& file_path : files)
        {
            // 读取文件
            std::string file_info;
            // 读取文件,读取失败就继续读取下一个
            if (!file::read(file_path, file_info))
                continue;
            doc_info_t html_info;
            // 解析指定文件,提取title
            if (!string_html::parser_title(file_info, html_info._title))
                continue;
            // 解析指定文件,提取context
            if (!string_html::parser_context(file_info, html_info._context))
                continue;
            // 解析指定文件,提取url
            if (!string_html::parser_url(file_path, src_path, html_info._url))
                continue;
#ifdef __TEST__DEBUG__2
            std::cout << "title: " << html_info._title << ' ';
            // std::cout << "context: " << html_info._context << ' ';
            std::cout << "url: " << html_info._url << std::endl;
#endif
            htmls.push_back(std::move(html_info));
        }
        return true;
    }

    bool save_html(const std::string& path, const std::vector<doc_info_t>& htmls)
    {
        std::ofstream fout;
        fout.open(path, std::ofstream::out | std::ofstream::binary);
        if (!fout.is_open())
        {
            // std::cerr << path << " open err" << std::endl;
            server_log(Fatal, "%s open err, err file: %s, err line: %s", path.c_str(), __FILE__, __LINE__);
            return false;
        }

        for (const doc_info_t& it : htmls)
        {
            std::string out_string = std::move(string_html::html_to_string(it));
            fout.write(out_string.c_str(), out_string.size());
        }

        fout.close();
        return true;
    }
}

int main()
{
    std::vector<std::string> files;
    
    // 读取所有html文档的文件路径
    if (!qyc::enum_file(qyc::src_path, files))
    {
        // std::cerr << "enum file name err" << std::endl;
        server_log(Fatal, "enum file name err, err file: %s, err line: %s", __FILE__, __LINE__);
        return 1;
    }
    
    // 读取html文档的信息,并解析清理
    std::vector<qyc::doc_info_t> htmls;
    if (!qyc::parse_html(files, htmls))
    {
        // std::cerr << "parse html err" << std::endl;
        server_log(Fatal, "parse html err, err file: %s, err line: %s", __FILE__, __LINE__);
        return 2;
    }

    // 将解析完毕的每个文档内容,写入存放文件
    if (!qyc::save_html(qyc::raw_file, htmls))
    {
        // std::cerr << "save html err" << std::endl;
        server_log(Fatal, "save html err, err file: %s, err line: %s", __FILE__, __LINE__);
        return 3;
    }

    return 0;
}